using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using System.Web;
using System.Web.Mail;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace Halide
{
	/// <summary>
	/// The HtmlForms class contains methods and properties for performing or evaluating form operations,
	/// or manipulating form objects.
	/// </summary>
	sealed public class HtmlForms
	{
		private static string _version = "2008.07.17A";

		private static string[] StatesList =
		{
			"AL",
			"AK",
			"AZ",
			"AR",
			"CA",
			"CO",
			"CT",
			"DE",
			"DC",
			"FL",
			"GA",
			"HI",
			"ID",
			"IL",
			"IN",
			"IA",
			"KS",
			"KY",
			"LA",
			"ME",
			"MD",
			"MA",
			"MI",
			"MN",
			"MS",
			"MO",
			"MT",
			"NE",
			"NV",
			"NH",
			"NJ",
			"NM",
			"NY",
			"NC",
			"ND",
			"OH",
			"OK",
			"OR",
			"PA",
			"RI",
			"SC",
			"SD",
			"TN",
			"TX",
			"UT",
			"VT",
			"VA",
			"WA",
			"WV",
			"WI",
			"WY"
		};

		/// <summary>
		/// Return the version number of the class; read-only.
		/// </summary>
		/// <value>
		/// A string with the version number of the class.
		/// </value>
		public static string Version
		{
			get
			{
				return _version;
			}
		}

		/// <summary>
		/// No constructor is necessary.
		/// </summary>
		private HtmlForms()
	    {
	    }

	    /// <summary>
	    /// Returns a field value from "form" or "querystring", in that order.
		/// Does not work with server-side controls.
	    /// </summary>
		/// <example>
		/// <code>
		/// string retVal = Halide.HtmlForms.RequestParam("FirstName");
		/// </code>
		/// </example>
	    /// <param name="ParamName">Field name for which a value is returned.</param>
	   	/// <returns>A form field value.</returns>
		public static string RequestParam(string ParamName)
		{
		    string Result = string.Empty;

			if (Halide.StringJuggler.FixNull(ParamName) == "")
			{
				return (string.Empty);
			}
			else
			{
		        Result = Convert.ToString(HttpContext.Current.Request[ParamName]);

			    return (Result == null) ? string.Empty : Result.Trim();
			}
		}

	    /// <summary>
		/// Loads submitted form fields into session variables, skipping VIEWSTATE hidden fields.
	    /// </summary>
		/// <example>
		/// <code>
		/// string[] converted = Halide.HtmlForms.RequestToSessions();
		/// </code>
		/// </example>
	   	/// <returns>String array of field names converted to Session variables.</returns>
		public static string[] RequestToSessions()
		{
			return RequestToSessions(null);
		}

		/// <summary>
		/// Loads submitted form fields into session variables, skipping VIEWSTATE hidden fields.
		/// </summary>
		/// <example>
		/// <code>
		/// string[] skipFields = new string[] { "hiddenID", "secretCode" };
		/// string[] converted = Halide.HtmlForms.RequestToSessions(skipFields);
		/// </code>
		/// </example>
	    /// <param name="except">String array of field names to ignore when processing.</param>
		/// <returns>string array of field names converted to Session variables.</returns>
		public static string[] RequestToSessions(string[] except)
		{
			bool excepts = (except != null);

			NameValueCollection frm;
			frm = HttpContext.Current.Request.Form;
			NameValueCollection flds = new NameValueCollection(frm);
			String[] theKeys = flds.AllKeys;

			int count = theKeys.Length;
			int y = 0;

			for(int counter2 = 0; counter2 < theKeys.Length; counter2++) {

				if(theKeys[counter2] == "__VIEWSTATE")
				{
					count--;
				}

				if(excepts)
				{
					for(int x = 0; x < except.Length; x++)
					{
						if(except[x].ToLower() == theKeys[counter2].ToLower())
						{
							count--;
						}
					}
				}
			}

			string[] fields = new string[count];

			int inc = 0;

			for(int counter = 0; counter < theKeys.Length; counter++) {

				if(theKeys[counter] != "__VIEWSTATE")
				{
					if(excepts)
					{
						for(int x = 0; x < except.Length; x++)
						{
							if(except[x].ToLower() == theKeys[counter].ToLower()) y++;
						}
					}					

					if(y == 0)
					{
						fields[inc++] = theKeys[counter];
						HttpContext.Current.Session[theKeys[counter]] = HttpContext.Current.Request.Form[theKeys[counter]];
					}

					y = 0;
				}
			}

			return fields;
		}

	    /// <summary>
		/// Loads form fields into context items, skipping VIEWSTATE hidden fields.
	    /// </summary>
		/// <example>
		/// <code>
		/// string[] converted = Halide.HtmlForms.RequestToContext();
		/// </code>
		/// </example>
		/// <returns>String array of field names converted to context items.</returns>
		public static string[] RequestToContext()
		{
			return RequestToContext(null);
		}

		/// <summary>
		/// Loads form fields into context items, skipping VIEWSTATE hidden fields.
		/// </summary>
		/// <example>
		/// <code>
		/// string[] skipFields = new string[] { "hiddenID", "secretCode" };
		/// string[] converted = Halide.HtmlForms.RequestToContext(skipFields);
		/// </code>
		/// </example>
		/// <param name="except">String array of fields to skip.</param>
		/// <returns>String array of field names converted to context items.</returns>
		public static string[] RequestToContext(string[] except)
		{
			bool excepts = true;

			if(except == null) excepts = false;

			NameValueCollection frm;
			frm = HttpContext.Current.Request.Form;
			NameValueCollection flds = new NameValueCollection(frm);
			String[] theKeys = flds.AllKeys;
			int count = theKeys.Length;

			for(int counter2 = 0; counter2 < theKeys.Length; counter2++) {
				if(theKeys[counter2] == "__VIEWSTATE" || Halide.StringJuggler.InStr(theKeys[counter2], "mce_editor") > 0) count--;

				if(excepts)
				{
					for(int x = 0; x < except.Length; x++)
					{
						if(except[x].ToLower() == theKeys[counter2].ToLower()) count--;
					}
				}
			}

			string[] fields = new string[count];
			bool y = true;
			int z = 0;

			for(int counter = 0; counter < theKeys.Length; counter++) {
				if(theKeys[counter] != "__VIEWSTATE" && Halide.StringJuggler.InStr(theKeys[counter], "mce_editor") < 1)
				{
					if(excepts)
					{
						for(int x = 0; x < except.Length; x++)
						{
							if(except[x].ToLower() == theKeys[counter].ToLower()) y = false;
						}
					}

					if(y)
					{
						fields[z++] = theKeys[counter];
						HttpContext.Current.Items[theKeys[counter]] = HttpContext.Current.Request.Form[theKeys[counter]];

						// HttpContext.Current.Response.Write(theKeys[counter] + ": " + HttpContext.Current.Request.Form[theKeys[counter]] + "<br><br>");
					}

					y = true;
				}
			}

			return fields;
		}

	    /// <summary>
	    /// Fill a drop down list box with items from a SQL database. Form must be server-side.
	    /// </summary>
		/// <example>
		/// <code>
		/// Halide.HtmlForms.FillListBox(
		///		DropDown1,
		///		"SELECT TOP 25 ID, Description FROM tablename;",
		///		"Description",
		///		"ID",
		///		true,
		///		true);
		/// </code>
		/// </example>
	    /// <param name="box">Server-side DropDownList form object.</param>
	    /// <param name="sql">SQL command string.</param>
	    /// <param name="DisplayField">SQL field used for the list item display.</param>
	    /// <param name="ValueField">SQL field to use for list item values.</param>
	    /// <param name="EmptyFirst">Clear out existing list items first?</param>
	    /// <param name="KeepOldValue">Keep previously selected item?</param>
		/// <returns>Nothing.</returns>
	    public static void FillListBox(DropDownList box, string sql, string DisplayField, string ValueField, bool EmptyFirst, bool KeepOldValue)
	    {
	        using (SqlConnection dbConnection = new SqlConnection(Halide.Database.SqlConnectionString))
	        {
	            dbConnection.Open();

	            using (SqlCommand cmd = new SqlCommand(sql, dbConnection))
	            {
	                using (SqlDataReader dr = cmd.ExecuteReader())
	                {
	                    ListItem l;

	                    string OldValue;
	                    OldValue = box.SelectedValue;

	                    box.Items.Clear();

	                    if (EmptyFirst)
	                    {
	                        l = new ListItem();
	                        box.Items.Add(l);
	                    }

	                    while (dr.Read())
	                    {
	                        l = new ListItem();
	                        l.Text = dr[DisplayField].ToString();
	                        l.Value = dr[ValueField].ToString();
	                        box.Items.Add(l);
	                    }

	                    try
	                    {
	                        if (KeepOldValue) box.SelectedValue = OldValue;
	                    }
	                    catch { }
	                }
	            }
	        }
	    }

		/// <summary>
		/// Fill a drop down list box with items from a SQL database. Form must be server-side.
		/// </summary>
		/// <example>
		/// <code>
		/// Halide.HtmlForms.FillListBox(
		///		DropDown1,
		///		"SELECT TOP 25 ID, Description FROM tablename;",
		///		"Description",
		///		"ID",
		///		true);
		/// </code>
		/// </example>
		/// <param name="box">Server-side DropDownList form object.</param>
		/// <param name="sql">SQL command string.</param>
		/// <param name="DisplayField">SQL field used for the list item display.</param>
		/// <param name="ValueField">SQL field to use for list item values.</param>
		/// <param name="EmptyFirst">Clear out existing list items first?</param>
		/// <returns>Nothing.</returns>
		public static void FillListBox(DropDownList box, string sql, string DisplayField, string ValueField, bool EmptyFirst)
	    {
	        FillListBox(box, sql, DisplayField, ValueField, EmptyFirst, true);
	    }

	    /// <summary>
	    /// Used to set the "checked" status of a radio button based on a lookup value.
	    /// </summary>
		/// <example>
		/// <code>
		/// string radio = "&lt;input type=\"radio\" value=\"1\"" + Halide.HtmlForms.SetRadio("1", variableName) + " /&gt;";
		/// </code>
		/// </example>
	    /// <param name="recval">Record value from database.</param>
	    /// <param name="strval">Value which determines if the radio button is checked.</param>
		/// <returns>Empty string if recval and strval are not equal, or ' checked="checked"'.</returns>
		public static string SetRadio(string recval, string strval)
		{
			if(recval == strval) return (" checked=\"checked\"");
			return String.Empty;
		}

		/// <summary>
		/// Enumeration with field types used in validating field values with the ValidateItem method.
		/// </summary>
		[Flags]
		public enum validationOptions
		{
			/// <summary>
			/// Validate only the length of the string.
			/// </summary>
			length,

			/// <summary>
			/// Validate as an E-mail address
			/// </summary>
			email,

			/// <summary>
			/// Validate as a list of e-mail addresses. Addresses can be separated with ",", "|", ";", "/", or spaces.
			/// </summary>
			emailList,

			/// <summary>
			/// Validate as a numeric value.
			/// </summary>
			number,

			/// <summary>
			/// Validate as a pure number; no commas, periods, or non-numeric characters.
			/// </summary>
			pureNumber,

			/// <summary>
			/// Validate as a number which is greater than zero.
			/// </summary>
			nonZero,

			/// <summary>
			/// Validate as currency.
			/// </summary>
			money,

			/// <summary>
			/// Validate as a date.
			/// </summary>
			date,

			/// <summary>
			/// Validate as time of day.
			/// </summary>
			time,

			/// <summary>
			/// Validate as a telephone number. Allows: 324-234-3433, 3242343434, (234)234-234, (234) 234-2343.
			/// </summary>
			telephone,

			/// <summary>
			/// Validate as a credit card number.
			/// <para>Matches major credit cards including: Visa (length 16, prefix 4);</para>
			/// <para>Mastercard (length 16, prefix 51-55);</para>
			/// <para>Diners Club/Carte Blanche (length 14, prefix 36, 38, or 300-305);</para>
			/// <para>Discover (length 16, prefix 6011);</para>
			/// <para>American Express (length 15, prefix 34 or 37).</para>
			/// <para>Saves the card type as a named group to facilitate further validation 
			/// against a "card type" checkbox in a program.</para>
			/// <para>All 16 digit formats are grouped 4-4-4-4 with an optional hyphen 
			/// or space between each group of 4 digits.</para>
			/// <para>The American Express format is grouped 4-6-5 with an optional hyphen or 
			/// space between each group of digits.</para>
			/// <para>Formatting characters must be consistant, i.e. if two groups are separated by a hyphen, 
			/// all groups must be separated by a hyphen for a match to occur.</para>
			/// </summary>
			creditCard,

			/// <summary>
			/// Validate as a U.S. 5-digit zip code.
			/// </summary>
			zipCode,

			/// <summary>
			/// Validate as a URL. Allows: http://www.yahoo.com, https://www.yahoo.com, ftp://www.yahoo.com.
			/// </summary>
			url,
			
			/// <summary>
			/// Validate as an IP address. Allows: 123.123.123.123, 192.168.1.1.
			/// </summary>
			ipAddress,

			/// <summary>
			/// Validate as a social security number. Allows: 123-45-6789, 232-432-1212.
			/// </summary>
			ssn,

			/// <summary>
			/// Validate as domain name. Allows: site.com, site.com:8080, http://www.site.com, et al.
			/// </summary>
			domain,

			/// <summary>
			/// Validate as first and last name.
			/// <para>Allows: christophersen,eric; christophersen, eric.</para>
			/// <para>Not allowed: christophersen ,eric.</para>
			/// </summary>
			name,

			/// <summary>
			/// Validate a 2-letter abbreviation as a valid state in the U.S.
			/// </summary>
			state
		}

		/// <summary>
		/// Verify that a given value is equal to a value in a delimitted list of provided values.
		/// </summary>
		/// <param name="value">Value to compare</param>
		/// <param name="ValueList">Delimitted list of possible matches for comparison.</param>
		/// <param name="Delimitter">Delimitter string which defines the delimitted list of values passed in parameter "ValueList"</param>
		/// <param name="ErrorMsg">Error message to return if match is not found.</param>
		/// <param name="UseCase">Set to true to compare values using case sensitivity, or false to ignore case.</param>
		/// <returns>Empty string on success, or an error message.</returns>
		public static string ValidateItem(string value, string ValueList, string Delimitter, string ErrorMsg, bool UseCase)
		{
			string retVal = ErrorMsg;

			if (!String.IsNullOrEmpty(ValueList) && !String.IsNullOrEmpty(value) && !String.IsNullOrEmpty(ErrorMsg))
			{
				string[] delimitter = { Delimitter };
				string[] values = ValueList.Split(delimitter, StringSplitOptions.RemoveEmptyEntries);

				if (values.Length > 0)
				{
					for (int x = 0; x < values.Length; x++)
					{
						if (!UseCase)
						{
							values[x] = values[x].ToLower();
							value = value.ToLower();
						}

						if (values[x] == value)
						{
							retVal = "";
						}
					}
				}

				else
				{
					retVal = "No comparison values passed to ValidateItem()";
				}
			}

			return (retVal);
		}

		/// <summary>
		/// Run data type and field length validation on a specific value.
		/// Certain types of validators obviate the need to specify a minimum or maximum length,
		/// like Halide.HtmlForms.validationOptions.email.
		/// <example>
		/// <code>
		/// string result = Halide.HtmlForms.ValidateItem(
		///		value,
		///		Halide.HtmlForms.validationOptions.email,
		///		0,
		///		0,
		///		false);
		/// </code>
		/// </example>
		/// <para>A common practice is to add error message fields underneath each of your form fields,
		/// and then use a single line to validate the input and display the error on the form, as well
		/// as set a global flag that identifies that there has been an error.</para>
		/// <example>
		/// <code>
		/// errorFlag +=
		///		EmailFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				EmailField.Value,
		///				Halide.HtmlForms.validationOptions.email,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		PhoneFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				PhoneField.Value,
		///				Halide.HtmlForms.validationOptions.telephone,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		SSNFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				SSNField.Value,
		///				Halide.HtmlForms.validationOptions.ssn,
		///				0,
		///				0,
		///				false);
		/// </code>
		/// </example>
		/// <para>In this way, you can check "errorFlag" to see if it's empty or null, in which case,
		/// there were no validation errors, otherwise, you know one or more validations failed.
		/// And in the same line, the error message for each field is filled with the error message,
		/// since ValidateItem() returns an empty string if the validation is successful, or a friendly
		/// error string if it fails.</para>
		/// </summary>
		/// <param name="value">Value to validate.</param>
		/// <param name="valType">Constant determining what type of validation.</param>
		/// <param name="minLength">Minimum length alowed.</param>
		/// <param name="maxLength">Maximum length allowed.</param>
		/// <param name="opt">Field is optional. Zero length validates, otherwise, full validation occurs.</param>
		/// <returns>Empty string if validation succeeds, error message on failure.</returns>
		public static string ValidateItem(string value, validationOptions valType, int minLength, int maxLength, bool opt)
		{
			string retVal = "";

			if (opt && value.Length < 1) return retVal;

			// Evaluate length of value if minLength and maxLengths are non-zero
			if (minLength > 0 && maxLength > 0)
			{
				if (value.Length > maxLength)
				{
					retVal += "Text can only be " + maxLength.ToString() + " character(s) long";
				}
				else
				{
					if (value.Length < minLength)
					{
						retVal += "Text must be " + minLength.ToString() + " character(s) or longer";
					}
				}
			}

			// If no length errors, validate data is of a specific format
			if (retVal == "")
			{
				if (valType == validationOptions.state)
				{
					bool flag = false;

					for (int x = 0; x < StatesList.Length; x++)
						if (value.ToLower() == StatesList[x].ToLower())
							flag = true;
		
					if (!flag)
					{
						retVal += "Not a State";
					}
				}

				if (valType == validationOptions.email)
				{
					if (!Halide.Identify.IsEmail(value))
					{
						retVal += "Invalid e-mail address format";
					}
				}

				if (valType == validationOptions.emailList)
				{
					// Invalid string
					if (value.Length < 6)
					{
						retVal += "Invalid e-mail address format";
					}
					else
					{
						// Only one email address? If not, check for multiple.
						if (!Halide.Identify.IsEmail(value))
						{
							string delim = "";

							if (delim == "" && value.IndexOf(",") > 0) delim = ",";
							if (delim == "" && value.IndexOf("|") > 0) delim = "|";
							if (delim == "" && value.IndexOf(";") > 0) delim = ";";
							if (delim == "" && value.IndexOf("/") > 0) delim = "/";
							if (delim == "" && value.IndexOf(" ") > 0) delim = " ";

							if (delim != "")
							{
								value = value.Replace(delim, ",");
								value = value.Replace(" ", "");

								while (value.IndexOf(",,") > 0) value = value.Replace(",,", ",");

								string[] addresses = value.Split(',');

								for (int x = 0; x < addresses.Length; x++)
								{
									if (!Halide.Identify.IsEmail(addresses[x]))
									{
										retVal += "One or more e-mail addresses are invalid";
									}
								}
							}
							else
							{
								retVal += "Must have one or more e-mail addresses";
							}
						}
					}
				}

				if (valType == validationOptions.number)
				{
					if (!Halide.Identify.IsNumeric(value))
					{
						retVal += "Text must be a numeric value";
					}
				}

				if (valType == validationOptions.pureNumber)
				{
					if (!Halide.Identify.IsPureNumeric(value))
					{
						retVal += "Text must only contain numbers";
					}
				}

				if (valType == validationOptions.nonZero)
				{
					if (!Halide.Identify.IsPureNumeric(value))
					{
						retVal += "Text must only contain numbers";
					}
					else
					{
						if (Convert.ToInt32(value) <= 0)
						{
							retVal += "Value must be greater than zero";
						}
					}
				}

				if (valType == validationOptions.money)
				{
					if (!Halide.Identify.IsCurrency(value))
					{
						retVal += "Text must be a currency value";
					}
				}

				if (valType == validationOptions.date)
				{
					if (!Halide.Identify.IsDate(value))
					{
						retVal += "Text must be a date";
					}
				}

				if (valType == validationOptions.telephone)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_US_TELEPHONE, value))
					{
						retVal += "Text must be a telephone number";
					}
				}

				if (valType == validationOptions.creditCard)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_CREDIT_CARD, value))
					{
						retVal += "Text must be a credit card number";
					}
				}

				if (valType == validationOptions.zipCode)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_US_ZIPCODE, value))
					{
						retVal += "Enter a 5-digit zip code";
					}
				}

				if (valType == validationOptions.url)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_URL, value))
					{
						retVal += "Text must be a URL";
					}
				}

				if (valType == validationOptions.ipAddress)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_IP_ADDRESS, value))
					{
						retVal += "Text must be an IP address";
					}
				}

				if (valType == validationOptions.ssn)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_SOCIAL_SECURITY, value))
					{
						retVal += "Text must be a social security number";
					}
				}

				if (valType == validationOptions.time)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_TIME, value) && !Halide.Identify.HasPattern(Halide.Identify.REGEX_TIME_24, value))
					{
						retVal += "Text must be a time of day";
					}
				}

				if (valType == validationOptions.domain)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_DOMAIN_NAME, value))
					{
						retVal += "Text must be a domain name";
					}
				}

				if (valType == validationOptions.name)
				{
					if (!Halide.Identify.HasPattern(Halide.Identify.REGEX_NAME_COMMA_NAME, value))
					{
						retVal += "Text must be last name, first name";
					}
				}
			}

			return retVal;
		}

		/// <summary>
		/// Run data type and field length validation on a specific value.
		/// Certain types of validators obviate the need to specify a minimum or maximum length,
		/// like Halide.HtmlForms.validationOptions.email.
		/// <example>
		/// <code>
		/// string result = Halide.HtmlForms.ValidateItem(
		///		value,
		///		Halide.HtmlForms.validationOptions.email,
		///		0,
		///		0);
		/// </code>
		/// </example>
		/// <para>A common practice is to add error message fields underneath each of your form fields,
		/// and then use a single line to validate the input and display the error on the form, as well
		/// as set a global flag that identifies that there has been an error.</para>
		/// <example>
		/// <code>
		/// errorFlag +=
		///		EmailFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				EmailField.Value,
		///				Halide.HtmlForms.validationOptions.email,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		PhoneFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				PhoneField.Value,
		///				Halide.HtmlForms.validationOptions.telephone,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		SSNFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				SSNField.Value,
		///				Halide.HtmlForms.validationOptions.ssn,
		///				0,
		///				0,
		///				false);
		/// </code>
		/// </example>
		/// <para>In this way, you can check "errorFlag" to see if it's empty or null, in which case,
		/// there were no validation errors, otherwise, you know one or more validations failed.
		/// And in the same line, the error message for each field is filled with the error message,
		/// since ValidateItem() returns an empty string if the validation is successful, or a friendly
		/// error string if it fails.</para>
		/// </summary>
		/// <param name="value">Value to validate.</param>
		/// <param name="valType">Constant determining what type of validation.</param>
		/// <param name="minLength">Minimum length alowed.</param>
		/// <param name="maxLength">Maximum length allowed.</param>
		/// <returns>Empty string if validation succeeds, error message on failure.</returns>
		public static string ValidateItem(string value, validationOptions valType, int minLength, int maxLength)
		{
			return ValidateItem(value, valType, minLength, maxLength, false);
		}

		/// <summary>
		/// Run data type and field length validation on a specific value.
		/// Certain types of validators obviate the need to specify a minimum or maximum length,
		/// like Halide.HtmlForms.validationOptions.email.
		/// <example>
		/// <code>
		/// string result = Halide.HtmlForms.ValidateItem(
		///		value,
		///		Halide.HtmlForms.validationOptions.email);
		/// </code>
		/// </example>
		/// <para>A common practice is to add error message fields underneath each of your form fields,
		/// and then use a single line to validate the input and display the error on the form, as well
		/// as set a global flag that identifies that there has been an error.</para>
		/// <example>
		/// <code>
		/// errorFlag +=
		///		EmailFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				EmailField.Value,
		///				Halide.HtmlForms.validationOptions.email,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		PhoneFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				PhoneField.Value,
		///				Halide.HtmlForms.validationOptions.telephone,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		SSNFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				SSNField.Value,
		///				Halide.HtmlForms.validationOptions.ssn,
		///				0,
		///				0,
		///				false);
		/// </code>
		/// </example>
		/// <para>In this way, you can check "errorFlag" to see if it's empty or null, in which case,
		/// there were no validation errors, otherwise, you know one or more validations failed.
		/// And in the same line, the error message for each field is filled with the error message,
		/// since ValidateItem() returns an empty string if the validation is successful, or a friendly
		/// error string if it fails.</para>
		/// </summary>
		/// <param name="value">Value to validate.</param>
		/// <param name="valType">Constant determining what type of validation.</param>
		/// <returns>Empty string if validation succeeds, error message on failure.</returns>
		public static string ValidateItem(string value, validationOptions valType)
		{
			return ValidateItem(value, valType, 0, 0, false);
		}

		/// <summary>
		/// Run field length validation on a specific value.
		/// <example>
		/// <code>
		/// string result = Halide.HtmlForms.ValidateItem(
		///		value,
		///		5,
		///		50);
		/// </code>
		/// </example>
		/// <para>A common practice is to add error message fields underneath each of your form fields,
		/// and then use a single line to validate the input and display the error on the form, as well
		/// as set a global flag that identifies that there has been an error.</para>
		/// <example>
		/// <code>
		/// errorFlag +=
		///		EmailFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				EmailField.Value,
		///				Halide.HtmlForms.validationOptions.email,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		PhoneFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				PhoneField.Value,
		///				Halide.HtmlForms.validationOptions.telephone,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		SSNFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				SSNField.Value,
		///				Halide.HtmlForms.validationOptions.ssn,
		///				0,
		///				0,
		///				false);
		/// </code>
		/// </example>
		/// <para>In this way, you can check "errorFlag" to see if it's empty or null, in which case,
		/// there were no validation errors, otherwise, you know one or more validations failed.
		/// And in the same line, the error message for each field is filled with the error message,
		/// since ValidateItem() returns an empty string if the validation is successful, or a friendly
		/// error string if it fails.</para>
		/// </summary>
		/// <param name="value">Value to validate.</param>
		/// <param name="minLength">Minimum length alowed.</param>
		/// <param name="maxLength">Maximum length allowed.</param>
		/// <returns>Empty string if validation succeeds, error message on failure.</returns>
		public static string ValidateItem(string value, int minLength, int maxLength)
		{
			return ValidateItem(value, validationOptions.length, minLength, maxLength, false);
		}

		/// <summary>
		/// Run data type validation on a specific value.
		/// <example>
		/// <code>
		/// string result = Halide.HtmlForms.ValidateItem(
		///		value,
		///		Halide.HtmlForms.validationOptions.email,
		///		false);
		/// </code>
		/// </example>
		/// <para>A common practice is to add error message fields underneath each of your form fields,
		/// and then use a single line to validate the input and display the error on the form, as well
		/// as set a global flag that identifies that there has been an error.</para>
		/// <example>
		/// <code>
		/// errorFlag +=
		///		EmailFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				EmailField.Value,
		///				Halide.HtmlForms.validationOptions.email,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		PhoneFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				PhoneField.Value,
		///				Halide.HtmlForms.validationOptions.telephone,
		///				0,
		///				0,
		///				false);
		///				
		/// errorFlag +=
		///		SSNFieldErrorMessage.InnerHtml =
		///			Halide.HtmlForms.ValidateItem(
		///				SSNField.Value,
		///				Halide.HtmlForms.validationOptions.ssn,
		///				0,
		///				0,
		///				false);
		/// </code>
		/// </example>
		/// <para>In this way, you can check "errorFlag" to see if it's empty or null, in which case,
		/// there were no validation errors, otherwise, you know one or more validations failed.
		/// And in the same line, the error message for each field is filled with the error message,
		/// since ValidateItem() returns an empty string if the validation is successful, or a friendly
		/// error string if it fails.</para>
		/// </summary>
		/// <param name="value">Value to validate.</param>
		/// <param name="valType">Constant determining what type of validation.</param>
		/// <param name="opt">Field is optional. Zero length validates, otherwise, full validation occurs.</param>
		/// <returns>Empty string if validation succeeds, error message on failure.</returns>
		public static string ValidateItem(string value, validationOptions valType, bool opt)
		{
			return ValidateItem(value, valType, 0, 0, opt);
		}

	// Outer Identify class
	}

// Outer namespace
}